/**
 *  @file Primitive.cpp
 */
#include "Primitive.h"

namespace cppflib
{

namespace lang
{

/*** various specializations for GenHashByType to generate hash value ***/

template <>
_DLLAPI u32_t GenHashByType(char value)
{
   return static_cast<u32_t>(static_cast<int>(value));
}

template <>
_DLLAPI u32_t GenHashByType(short value)
{
   return static_cast<u32_t>(static_cast<int>(value));
}

template <>
_DLLAPI u32_t GenHashByType(bool value)
{
   return static_cast<u32_t>(static_cast<int>(value));
}

template <>
_DLLAPI u32_t GenHashByType(u8_t value)
{
   return (static_cast<u32_t>(value) & 0xff);
}

template <>
_DLLAPI u32_t GenHashByType(wc_t value)
{
   return (static_cast<u32_t>(value) & 0xffff);
}

template <>
_DLLAPI u32_t GenHashByType(u16_t value)
{
   return (static_cast<u32_t>(value) & 0xffff);
}

template <>
_DLLAPI u32_t GenHashByType(int value)
{
   return static_cast<u32_t>(value);
}

template <>
_DLLAPI u32_t GenHashByType(u32_t value)
{
   return value;
}

static u32_t __GenHashByRawBytes(int typeSize, const u8_t * pData)
{
   u32_t h = 0;
   for (int i = 0 ; i < typeSize; ++i) {
      u32_t htemp = static_cast<u32_t>((*pData++) & 0xff) << ((8 * i) % 32);
      h ^= htemp;
   }

   return h;
}

template <>
_DLLAPI u32_t GenHashByType(i64_t value)
{
   return __GenHashByRawBytes(sizeof(i64_t), reinterpret_cast<const u8_t*>(&value));
}

template <>
_DLLAPI u32_t GenHashByType(u64_t value)
{
   return __GenHashByRawBytes(sizeof(u64_t), reinterpret_cast<const u8_t*>(&value));
}

template <>
_DLLAPI u32_t GenHashByType(float value)
{
   return __GenHashByRawBytes(sizeof(float), reinterpret_cast<const u8_t*>(&value));
}

template <>
_DLLAPI u32_t GenHashByType(double value)
{
   return __GenHashByRawBytes(sizeof(double), reinterpret_cast<const u8_t*>(&value));
}

template <>
_DLLAPI u32_t GenHashByType(ptrany_t value)
{
   return __GenHashByRawBytes(sizeof(ptrany_t), reinterpret_cast<const u8_t*>(&value));
}


}  // end of namespace lang

}  // end of namespace cppflib

